/* $Header: p_aux.c,v 2.2 01/10/02 10:27:46 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:  aux.c                                                 */
/* ============                                                        */
/*                                                                     */
/* Author: wikfors                                                     */
/*                                                                     */
/* MODULE PURPOSE:  perform any control functions needed for the aux   */
/*                  pneumatic zones.  Any adc conversions are and      */
/*                  calibrations will be performed here.               */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <error.h>
#include <exception.h>
#include <err_handler.h>
#include <p_wkfile.h>
#include <p_status.h>
#include <list_mgmt.h>
#include <math.h>
#include <keyboard.h>
#include <glp.h>
#include <p_filter.h>
#include <TUIInfo.h>


/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/


#include "proto.h"


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

#define AUX_READY_TICS 250  /* 250 tics @ 50Hz = 5 sec */

#define ACTUAL_TEMP_DELAY        18

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/


/**begin_proto**/

U_INT16 RangeCheckAuxPres( pAUX_STATUS status, U_INT16 Pi )

/**end_proto**/
{
     U_INT16 p_limit;

     p_limit = status->P_Sensor_Range;

     if ( Pi > p_limit )
     {
         status->Ready.Pres.Capped = TRUE;
         Pi =  p_limit;
     }
     else
     {
         status->Ready.Pres.Capped = FALSE;
     }

     return Pi;
}

/**begin_proto**/

#pragma SECTION PROG=rom3

/**end_proto**/

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ControlAux  ( pAUX_STATUS status , pAUXILIARY_STATUS aux_status )

/**end_proto**/
{

       U_INT16  Pi;


       if (( !status->Config->Functional ) || ( status->On_Off == OFF ))
       {
            status->Adc_Setpt = 0;
            status->Ready.Pres.Controlled = FALSE;
            return;
       }

       Filter16Bits( &status->Actual_Oven_Temp, status->Setpt_Oven_Temp, ACTUAL_TEMP_DELAY );
       status->Setpt_Oven_Temp = GetCurrentOvenTemp();

       status->Ready.Pres.Controlled = TRUE;

       if ( status->Controlled_By_Column )
       {
           Pi = FindSourcePressureWithColumns ( status->Position, status->Dcm2_Per_IU, status->Setpt_Oven_Temp );
       }
       else
       {
           Pi = QuadWordMultiplyDivide( status->Ramp_Setpt.Ramp_Pressure,
                                        status->Ramp_Setpt.Ramp_Pres_Scaling,
                                        status->Dcm2_Per_IU );
       }

       /* this is the ntp value we will control to. */
       status->Aux_Pressure_Setpt = Pi;


       /* use a two stage filter to emulate what the pres setpt-actual loop will do to the setpt */
       /* this delayed value will be passed to the columns and used anywhere pres setpt is to be */
       /* displayed                                                                              */

       if (!status->Slam_Pres_Setpt)
       {
          Filter16Bits( &status->Intermediate_Pres,          Pi,                        AUX_PRES_FILTER_RATE );
          Filter16Bits( &status->Delayed_NTP_Aux_Pres_Setpt, status->Intermediate_Pres, AUX_PRES_DELAY       );
       }
       else
       {
           /* we want the displayed setpt to jump to the pulse value when pulse is first enabled */
          status->Intermediate_Pres          = Pi;
          status->Delayed_NTP_Aux_Pres_Setpt = Pi;
       }

       /* update the columns with this new delayed ntp pres setpt */

       if ( Inst_Config.Pneu.Column_1.Source == status->Position )
       {
             OverideColumnSetpt ( status->Delayed_NTP_Aux_Pres_Setpt, &Inst_Status.Pneu.Column_1, status->Dcm2_Per_IU );
       }
       if ( Inst_Config.Pneu.Column_2.Source == status->Position )
       {
             OverideColumnSetpt ( status->Delayed_NTP_Aux_Pres_Setpt, &Inst_Status.Pneu.Column_2, status->Dcm2_Per_IU );
       }
       
       Pi = RangeCheckAuxPres( status, Pi );



       /*** *** ***  NTP - REAL   break point  *** *** *** ***/


       if (( status->Has_Column ) && ( Pi != 0 ))
       {
            Pi = CorrectForAtmospheric( Pi,
                                        status->Position, &status->Flow_Correct_Ratio, 
                                        status->Setpt_Oven_Temp, 
                                        ( status->Ready.Start     ||
                                          status->Ready.On        || 
                                          status->Slam_Pres_Setpt || 
                                          status->Ready.Setpt_Change ), 
                                        FALSE );
       }

       /* don't need this any more */
       status->Slam_Pres_Setpt = FALSE;

       status->Compensated_Pressure = Pi;

       Filter16Bits( &status->Filtered_Aux_Pressure_Setpt, Pi, AUX_PRES_FILTER_RATE );

       switch ( status->Position )
       {
          case AUX_3:  status->Adc_Setpt = PresToVolts ( status->Filtered_Aux_Pressure_Setpt, 
                                             &aux_status->Tcomp_Tables->Aux_3,
                                             aux_status->Tcomp_Tables->Thermistor.Module_Temperature,
                                             status->Calib.Offset, status->Calib.Gain );
                       break;

          case AUX_4:  status->Adc_Setpt = PresToVolts ( status->Filtered_Aux_Pressure_Setpt, 
                                             &aux_status->Tcomp_Tables->Aux_4,
                                             aux_status->Tcomp_Tables->Thermistor.Module_Temperature,
                                             status->Calib.Offset, status->Calib.Gain );
                       break;

          case AUX_5:  status->Adc_Setpt = PresToVolts ( status->Filtered_Aux_Pressure_Setpt, 
                                             &aux_status->Tcomp_Tables->Aux_5,
                                             aux_status->Tcomp_Tables->Thermistor.Module_Temperature,
                                             status->Calib.Offset, status->Calib.Gain );
                       break;
       }

       /* do to filtering on the actual (both bby the 331 and pcb2) there is a time delay.  */
       /* this filter is used to delay the setpt at the same rate as the actual is delayed. */
       /* readiness will compare the two delayed values.                                    */

       Filter16Bits( &status->Delayed_Aux_Pressure_Setpt, status->Filtered_Aux_Pressure_Setpt, AUX_PRES_DELAY );

}

/***********************************************************************/
/* FUNCTION:   CalcAuxPressure                                         */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:    calculate the actual (guage) pressure of this aux from  */
/*             it's adc reading.                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

void CalcAuxPressure ( pAUX_STATUS status, pAUXILIARY_STATUS aux_status )

/**end_proto**/

{
    U_INT16 aux_pressure;
    U_INT32 ignored = 0;
     

    if ( !status->Config->Functional ) 
    {
        return;
    }
     
    switch ( status->Position )
    {
       case AUX_3:
                    aux_pressure      = VoltsToPres ( status->Adc_Actual,
                                          &aux_status->Tcomp_Tables->Aux_3,
                                          aux_status->Tcomp_Tables->Thermistor.Module_Temperature,
                                          status->Calib.Offset,
                                          status->Calib.Gain );
                    break;
       case AUX_4:
                    aux_pressure      = VoltsToPres ( status->Adc_Actual,
                                          &aux_status->Tcomp_Tables->Aux_4,
                                          aux_status->Tcomp_Tables->Thermistor.Module_Temperature,
                                          status->Calib.Offset,
                                          status->Calib.Gain );
                    break;
       case AUX_5:
                    aux_pressure      = VoltsToPres ( status->Adc_Actual,
                                          &aux_status->Tcomp_Tables->Aux_5,
                                          aux_status->Tcomp_Tables->Thermistor.Module_Temperature,
                                          status->Calib.Offset,
                                          status->Calib.Gain );
                    break;

       default:     aux_pressure      = 0;  /* keep lint happy */
    }
         
    Filter16Bits( &status->Filtered_Current_Pressure,   aux_pressure, AUX_PRES_FILTER_RATE );

    if ( status->Has_Column )
    {
       status->NTP_Adjusted_Current_Pressure = CorrectToNTP( aux_pressure, 
                                                             status->Position,
                                                             &ignored, 
                                                             status->Actual_Oven_Temp, 
                                                             status->Flow_Correct_Ratio );

       if ( Inst_Config.Pneu.Column_1.Source == status->Position )
            CalcColumnActuals( &Inst_Status.Pneu.Column_1, status->Actual_Oven_Temp );

       if ( Inst_Config.Pneu.Column_2.Source == status->Position )
            CalcColumnActuals( &Inst_Status.Pneu.Column_2, status->Actual_Oven_Temp );

    }
    else
    {
       status->NTP_Adjusted_Current_Pressure = aux_pressure;
    }
  
    (void) ignored;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 CheckAuxPresReadiness( pAUX_STATUS status )

/**end_proto**/
{

    status->Ready.Pres.Setpt  = status->Delayed_Aux_Pressure_Setpt;
    status->Ready.Pres.Actual = status->Filtered_Current_Pressure;

    status->Ready.Pres.Difference = ( status->Ready.Pres.Actual - status->Ready.Pres.Setpt );

    switch ( status->Dcm2_Per_IU )
    {
    case  80: status->Ready.Pres.Bound =  (  3447 /  80 );  /* .05 PSI = 3447.378 Dynes/cm*cm */
              break;
    case 160: status->Ready.Pres.Bound =  (  6894 / 160 );  /* .1  PSI = 6894.757 Dynes/cm*cm */
              break;
    case 320: status->Ready.Pres.Bound =  ( 34473 / 320 );  /* .5  PSI = 34473.85 Dynes/cm*cm */
              break;
              /* default case to keep lint happy */
    default:  status->Ready.Pres.Bound =  (  6894 / 160 );  /* .1  PSI = 6894.757 Dynes/cm*cm */
    }

    status->Ready.Pres.In_Bounds = (status->Ready.Pres.Difference < 0) ?
                                    status->Ready.Pres.Difference > -status->Ready.Pres.Bound :
                                    status->Ready.Pres.Difference <  status->Ready.Pres.Bound ;

    EvalPneuReady( &status->Ready.Pres,
                   ( CountAuxChangeRequests( status ) != 0 ) ||
                     status->Ready.Setpt_Change              || 
                     status->Ready.Capped                    ||
                     status->Ready.Pres.Temp_Exceeds_CF_Max  ||
                     status->Ready.On,
                   status->Shutdown,
                   status->Ready.Pres.In_Bounds,
                   status->Ready.Pres.Controlled && ( status->Wkfile->On_Off == ON ),
                   status->Ready.Time_Program_Change,
                   EVENT_TIMEOUT / READY_EVAL_PERIOD,
                   status->Wkfile->Pres_Equib_Time / READY_EVAL_PERIOD    );


    return status->Ready.Pres.Reported_Ready == FALSE;
}

/**begin_proto**/

void CheckAuxReadiness( pAUX_STATUS status )

/**end_proto**/

{

    U_INT8   pres_readiness;

    pres_readiness = CheckAuxPresReadiness( status );

    status->Ready.Setpt_Change = FALSE;
    status->Ready.Pres.Capped  = FALSE;
    status->Ready.On           = FALSE;
    status->Ready.Start        = FALSE;

    switch ( status->Position )
    {
       case AUX_3: 
          if ( pres_readiness )
          { 
           /* 
             SetNewException(AUX_3_PRES, 
                             ConvertPresIuToDisplay(status->Filtered_Current_Pressure,
                                                    status->Dcm2_Per_IU ),
                             (INT32)GLP_AUX_3_PRES_NR );
                             */
            TUI_addInfo(ERROR_READY_CH1,ERROR_ALWAYS);
          }
          else
          {
             //ClearNewException ( AUX_3_PRES );
             TUI_deleteInfo(ERROR_READY_CH1);
          }
          break;

       case AUX_4: 
          if ( pres_readiness ) 
          {
            /*
             SetNewException(AUX_4_PRES, 
                             ConvertPresIuToDisplay(status->Filtered_Current_Pressure,
                                                    status->Dcm2_Per_IU ),
                             (INT32)GLP_AUX_4_PRES_NR );
                             */

            TUI_addInfo(ERROR_READY_CH2,ERROR_ALWAYS);
          }
          else
          {
            //ClearNewException ( AUX_4_PRES );
            TUI_deleteInfo(ERROR_READY_CH2);
          }
          break;

       case AUX_5: 
          if ( pres_readiness ) 
          {
            /*
             SetNewException(AUX_5_PRES, 
                             ConvertPresIuToDisplay(status->Filtered_Current_Pressure,
                                                    status->Dcm2_Per_IU ),
                             (INT32)GLP_AUX_5_PRES_NR );
                             */
            TUI_addInfo(ERROR_READY_CH3,ERROR_ALWAYS);
          }
          else
          {
            //ClearNewException ( AUX_5_PRES );
            TUI_deleteInfo(ERROR_READY_CH3);
          }
          break;
    }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void  SlamAuxSetpt ( pAUX_STATUS status )

/**end_proto**/
{
     status->Slam_Pres_Setpt     = TRUE;
     status->Ready.Setpt_Change  = TRUE;
}


/**begin_proto**/

void  SlamAuxPresSetpt ( U_INT16 pressure, pAUX_STATUS status )

/**end_proto**/
{

     status->Ramp_Setpt.Ramp_Pressure = pressure;
     status->Slam_Pres_Setpt = TRUE;
     status->Ready.Setpt_Change  = TRUE;

}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void TwiddleAuxSetptChangedFlag ( pAUX_STATUS status )

/**end_proto**/
{
     status->Ready.Setpt_Change = TRUE;
}

/**begin_proto**/

#pragma SECTION UNDO

/**end_proto**/
